package AbstractTests;

import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import Impl.Dir;
import Impl.Terrain;
import Impl.Type;
import Services.MoteurJeuService;
import Services.TerrainService;

public abstract class AbstractScenariiTest {
	private MoteurJeuService moteur;
	private TerrainService terrain;
	
	protected final MoteurJeuService getMoteur() {
		return moteur;
	}
	protected final TerrainService getTerrain() {
		return terrain;
	}
		
	protected final void setMoteur(MoteurJeuService moteur) {
		this.moteur = moteur;
	}
	protected final void setTerrain(TerrainService terrain) {
		this.terrain = terrain;
	}
	
	@Before
	public abstract void beforeTests(); 

	@After
	public final void afterTests() {
		moteur = null;
		terrain = null;
	}
	
	@Test // Le joueur se deplace du bord gauche de la grille de jeu, au bord droit.
	public void scenariiTest_1(){
		TerrainService terrain = new Terrain();
		terrain.init(3, 3);
		terrain.addObject(1, 2, Type.Diamant);
		terrain.addObject(2, 2, Type.SortieFermee);
		terrain.startTerrain();
		moteur.init(5, terrain);
		
		moteur.moveHero(Dir.Gauche);
		moteur.moveObjects();
		moteur.verif();
		

		assertTrue(moteur.estFinie()==false);
		assertTrue(moteur.estGagne()==false);
		assertTrue(moteur.haveHeroMove()==false);
		assertTrue(moteur.haveObjectMove()==false);
		assertTrue(moteur.getPasRestants()==4);
		assertTrue(moteur.getTerrain().equals(terrain));
	}
	@Test // Le joueur gagne une partie en rentrant dans une sortie ouverte
	public void scenariiTest_2(){
		TerrainService terrain = new Terrain();
		terrain.init(3, 3);
		terrain.addObject(2, 1, Type.Diamant);
		terrain.addObject(2, 2, Type.SortieFermee);
		terrain.startTerrain();
		moteur.init(5, terrain);
		
		moteur.moveHero(Dir.Droite);
		moteur.moveObjects();
		moteur.verif();
		moteur.moveHero(Dir.Bas);
		moteur.moveObjects();
		moteur.verif();
		

		assertTrue(moteur.estFinie()==true);
		assertTrue(moteur.estGagne()==true);
		assertTrue(moteur.haveHeroMove()==false);
		assertTrue(moteur.haveObjectMove()==false);
		assertTrue(moteur.getPasRestants()==3);
		assertTrue(moteur.getTerrain().equals(terrain));
	}
	@Test // Le joueur meurt ecrase par un diamant
	public void scenariiTest_3(){
		TerrainService terrain = new Terrain();
		terrain.init(3, 3);
		terrain.addObject(2, 2, Type.Diamant);
		terrain.addObject(3, 2, Type.SortieFermee);
		terrain.startTerrain();
		moteur.init(5, terrain);
		
		moteur.moveHero(Dir.Droite);
		moteur.moveObjects();
		moteur.verif();
		moteur.moveHero(Dir.Rien);
		moteur.moveObjects();
		moteur.verif();
		

		assertTrue(moteur.estFinie()==true);
		assertTrue(moteur.estGagne()==false);
		assertTrue(moteur.haveHeroMove()==false);
		assertTrue(moteur.haveObjectMove()==false);
		assertTrue(moteur.getPasRestants()==3);
		assertTrue(moteur.getTerrain().equals(terrain));
	}
	@Test // Le joueur perd car le temps imparti est fini
	public void scenariiTest_4(){
		TerrainService terrain = new Terrain();
		terrain.init(3, 3);
		terrain.addObject(2, 2, Type.Diamant);
		terrain.addObject(3, 2, Type.SortieFermee);
		terrain.startTerrain();
		moteur.init(2, terrain);
		
		moteur.moveHero(Dir.Droite);
		moteur.moveObjects();
		moteur.verif();
		moteur.moveHero(Dir.Gauche);
		moteur.moveObjects();
		moteur.verif();
		

		assertTrue(moteur.estFinie()==true);
		assertTrue(moteur.estGagne()==false);
		assertTrue(moteur.haveHeroMove()==false);
		assertTrue(moteur.haveObjectMove()==false);
		assertTrue(moteur.getPasRestants()==0);
		assertTrue(moteur.getTerrain().equals(terrain));
	}
}
